package ngat.oss;

import ngat.util.*;

import java.util.*;
import java.io.*;
import java.net.*;
import java.text.*;

import ngat.util.*;

public class GlobalSettings extends ConfigurationProperties {
    
    public static final String DEFAULT_OSS_NAME = "OSS";	   
    
    public static final int DEFAULT_OSS_VERSION = 0;	  
    
    public static final int DEFAULT_PRIMARY_COMMAND_PORT = 7910;
    
    public static final int DEFAULT_SECONDARY_COMMAND_PORT = 7920;
    
    public static final int DEFAULT_PROXY_PORT = 6677;
    
    public static final String DEFAULT_PROXY_HOST = "localhost";
    
    public static final boolean DEFAULT_USE_PROXY = false;
    
    public static final long DEFAULT_SERVER_TIMEOUT = 4000;
    
    public static final int MAXIMUM_SERVER_CONNECTIONS = 5;
    
    public static final int DEFAULT_TQ_BUFF_SIZE = 20;
    
    public static final int DEFAULT_TQ_LEVELS = 5;
    
    public static final int DEFAULT_TQ_VECTOR_SIZE = 10;
    
    public static final long DEFAULT_TQ_THRESHOLD = 200000;
    
    public static final boolean DEFAULT_TQ_SWEEP_ENABLED = false;
			  
   
    /** 
     * OSS Server Configuration info.
     */

    /** 
     * The identity of the OSS (used in messages).
     */
    private String ossName;
   
    public String getOssName() { return ossName;}

    public void setOssName(String in) { ossName = in;}

    /** 
     * Version number of the OSS (used in messages).
     */
    private int  ossVersion;
    
    public int getOssVersion() { return ossVersion;}

    public void setOssVersion(int in) { ossVersion = in;}

    /** 
     * The port which the Controller listens to for transaction requests.
     */
    private int serverPrimaryCommandPort;

    public int getServerPrimaryCommandPort() { return serverPrimaryCommandPort;}

    public void setServerPrimaryCommandPort(int in) { serverPrimaryCommandPort = in;}

    /** 
     * Alternative port for Controller to listen on. Used by CTRL clients to
     * disallow access to other clients when server is PAUSED.
     */
    private int serverSecondaryCommandPort;
    
    public int getServerSecondaryCommandPort() { return serverSecondaryCommandPort;}
    
    public void setServerSecondaryCommandPort(int in) { serverSecondaryCommandPort = in;}

    /** 
     * Optional port to connect a Proxy server to (only used when testing).
     */
    private int proxyCommandPort;
    
    public int getProxyCommandPort() { return proxyCommandPort;}
    
    public void setProxyCommandPort(int in) { proxyCommandPort = in;}
    
    /** 
     * Optional host address for Proxy server.
     */
    private InetAddress proxyCommandHost;

    public InetAddress getProxyCommandHost() { return proxyCommandHost;}

    public void setProxyCommandHost(InetAddress in) { proxyCommandHost = in;}
    
    /** 
     * True if a Proxy server is to be used.
     */
    private boolean useProxy;

    public boolean useProxy() { return useProxy;}

    public void setUseProxy(boolean in) { useProxy = in;}

    /** 
     * Timeout period for the Controller. This is the length of time 
     * the Controller will block on ServerSocket.accept() before it 
     * wakes up to test whether it has been terminated.
     */
    private long serverTimeoutInterval;

    public long getServerTimeoutInterval() { return serverTimeoutInterval;}

    public void setServerTimeoutInterval(long in) { serverTimeoutInterval = in;}
    
    /** 
     * Maximum number of clients which may queue up for a TCP socket 
     * connection. This will be platform dependant - it is upto the
     *  TCP implementation on the host.
     */
    private int maximumConnections;

    public int getMaximumConnections() { return maximumConnections;}

    public void setMaximumConnections(int in) { maximumConnections = in;}

    /** 
     * Length of the transaction queue buffer. (i.e. how many objects 
     * can be fitted in at each priority level.
     */
    private int transQBuffSize;

    public int getTransQBuffSize() { return transQBuffSize;}

    public void setTransQBuffSize(int in) { transQBuffSize = in;}
    
    /** 
     * Number of priority levels in the transaction queue.
     */
    private int transQLevels;

    public int getTransQLevels() { return transQLevels;}

    public void setTransQLevels(int in) { transQLevels = in;}
    
    /** 
     * Size of the transaction queue waiting list. The number of 
     * simultaneous threads which can be blocked waiting for a  
     * lock on the transaction queue.
     */
    private int transQVectorSize;

    public int getTransQVectorSize() { return transQVectorSize;}

    public void setTransQVectorSize(int in) { transQVectorSize = in;}
    
    /** 
     * Maximum time a transaction should be blocked on a low level of
     *  the transaction queue before being pushed upwards - 
     *  (only when sweeping is enabled).
     */
    private long transQSweepThreshold;

    public long getTransQSweepThreshold() { return transQSweepThreshold;}

    public void setTransQSweepThreshold(long in) { transQSweepThreshold = in;}
    
    /** 
     * True if the transaction queue is swept for long delayed 
     * transactions.
     */
    private boolean sweepTransQ;

    public boolean sweepTransQ() { return sweepTransQ;}

    public void setSweepTransQ(boolean in) { sweepTransQ = in;}
    
    /** 
     * Interval for reader/writer threads to poll the transaction
     *  queue (msecs).
     */
    private long transQPollInterval;

    public long getTransQPollInterval() { return transQPollInterval;}

    public void setTransQPollInterval(long in) { transQPollInterval = in;}
    
    /** 
     * Interval for reader/writer threads to poll a TSConnectThread's
     * response buffer (msecs).
     */
    private long responseBuffPollInterval;

    public long getResponseBuffPollInterval() { return responseBuffPollInterval;}

    public void setResponseBuffPollInterval(long in) { responseBuffPollInterval = in;}
        

    /**  
     * Filepath for error logging (if enabled).
     */
    private File errorLogFile;

    public File getErrorLogFile() { return errorLogFile;}

    public void setErrorLogFile(File in) { errorLogFile = in;}

   
    /**  
     * Filepath for schedule logging (if enabled).
     */
    private File scheduleLogFile;

    public File getScheduleLogFile() { return scheduleLogFile;}

    public void setScheduleLogFile(File in) { scheduleLogFile = in;}
    
   

    /** 
     * Filepath for traffic logging (if enabled).
     */
    private File trafficLogFile;

    public File getTrafficLogFile() { return trafficLogFile;}

    public void setTrafficLogFile(File in) { trafficLogFile = in;}
      
  
    /** 
     * Filepath for performance logging (if enabled).
     */
    private File performanceLogFile;

    public File getPerformanceLogFile() { return performanceLogFile;}
    
    public void setPerformanceLogFile(File in) { performanceLogFile = in;}


    /** 
     * Filepath for software trace logging (if enabled).
     */
    private File traceLogFile;

    public File getTraceLogFile() { return traceLogFile;}
    
    public void setTraceLogFile(File in) { traceLogFile = in;}
    
   
   
    /** 
     * File Directory path for the Phase II database. 
     * (absolute path or relative to base).
     */
    private File databaseFile;

    public File getDatabaseFile() { return databaseFile;}

    public void setDatabaseFile(File in) { databaseFile = in;}
    
    /** 
     * Location of the Telescope environment settings.
     */
    private File telescopeParametersFile;
    
    public File getTelescopeParametersFile() { return telescopeParametersFile;}

    public void setTelescopeParametersFile(File in) { telescopeParametersFile = in;}

    /** 
     * Location of the password table. 
     * (absolute path or relative to base).
     */
    private File passwordTableFile;

    public File getPasswordTableFile() { return passwordTableFile;}

    public void setPasswordTableFile(File in) { passwordTableFile = in;}
    
    /** 
     * Location of the authorization table. 
     * (absolute path or relative to base).
     */
    private File authorizationTableFile;
    
    public File getAuthorizationTableFile() { return authorizationTableFile;}

    public void setAuthorizationTableFile(File in) { authorizationTableFile = in;}

    /** 
     * Location of the scheduling parameter settings.
     */
    private File schedulingParametersFile;

    public File getSchedulingParametersFile() { return schedulingParametersFile;}

    public void setSchedulingParametersFile(File in) { schedulingParametersFile = in;}

    
    /** 
     * Location of the weighting function parameters.
     */
    private File weightingParametersFile;

    public File getWeightingParametersFile() { return weightingParametersFile;}

    public void setWeightingParametersFile(File in) { weightingParametersFile = in;}

    
    /** 
     * Location of the client-settings.
     */
    private File clientSettingsFile;
 
    public File getClientSettingsFile() { return clientSettingsFile;}

    public void setClientSettingsFile(File in) { clientSettingsFile = in;}

    /**
     * Location of the Instrument properties.
     */
    private File instrumentsFile;
 
    public File getInstrumentsFile() { return instrumentsFile;}

    public void setInstrumentsFile(File in) { instrumentsFile = in;}


    /** 
     * Location of the news articles file.
     */
    private File newsTableFile;

    public File getNewsTableFile() { return newsTableFile;}

    public void setNewsTableFile(File in) { newsTableFile = in;}
   
    /** 
     * Base directory for locating client (P2T) upgrades.
     */
    private File clientResourcesBaseFile;

    public File getClientResourcesBaseFile() { return clientResourcesBaseFile;}

    public void setClientResourcesBaseFile(File in) { clientResourcesBaseFile = in;}

    /** 
     * Transaction Manager Config file.
     */
    private File  dtmsConfigFile;

    public File getDtmsConfigFile() { return dtmsConfigFile;}

    public void setDtmsConfigFile(File in) { dtmsConfigFile = in;}

    public GlobalSettings() {
	super();	
    }

    public void configure(File file) throws IOException, IllegalArgumentException {
	load(new FileInputStream(file));
    	
	ossName    = getProperty("oss.name", DEFAULT_OSS_NAME);	   
	
	ossVersion = getIntValue("oss.version", DEFAULT_OSS_VERSION);	  
	
	serverPrimaryCommandPort = getIntValue("server.primary.command.port",
					       DEFAULT_PRIMARY_COMMAND_PORT);
	
	serverSecondaryCommandPort = getIntValue("server.secondary.command.port",
						 DEFAULT_SECONDARY_COMMAND_PORT);	
	useProxy = getBooleanValue("use.proxy", DEFAULT_USE_PROXY);
	
	serverTimeoutInterval = getLongValue("server.timeout.interval", DEFAULT_SERVER_TIMEOUT);
	
	maximumConnections = getIntValue("maximum.connections", MAXIMUM_SERVER_CONNECTIONS);
	
	transQBuffSize = getIntValue("trans.Q.buff.size", DEFAULT_TQ_BUFF_SIZE);
	
	transQLevels = getIntValue("trans.Q.levels" , DEFAULT_TQ_LEVELS);
	
	transQVectorSize = getIntValue("trans.Q.vector.size", DEFAULT_TQ_VECTOR_SIZE);
	
	transQSweepThreshold = getLongValue( "trans.Q.sweep.threshold", DEFAULT_TQ_THRESHOLD);
	
	sweepTransQ = getBooleanValue("trans.Q.sweep.enabled", DEFAULT_TQ_SWEEP_ENABLED);	
	   	
	String valStr = null;

	// Pointer to Database Directory.
	valStr = getProperty("database.dir", "");
	if (valStr.startsWith(File.separator))
	    databaseFile = new File(valStr);
	else 
	    databaseFile = new File(ServerContext.getBaseFile(), valStr);
	if (!databaseFile.isDirectory()) 
	    throw new IllegalArgumentException("Illegal value for <database.dir> "+valStr);	
	
	// Pointer to Telescope Parameters.
	valStr = getProperty("telescope.parameters.file", "config/telescope.properties");
	if (valStr.startsWith(File.separator))
	    telescopeParametersFile = new File(valStr);
	else 
	    telescopeParametersFile = new File(ServerContext.getBaseFile(), valStr);	    
	if (!telescopeParametersFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <telescope.parameters.file> "+valStr);	
	   
	// Pointer to Password Table.
	valStr = getProperty("password.table.file", "config/password.crypto");
	if (valStr.startsWith(File.separator))
	    passwordTableFile = new File(valStr);
	else 
	    passwordTableFile = new File(ServerContext.getBaseFile(), valStr);	
	if (!passwordTableFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <password.table.file> "+valStr);	
	    
	// Pointer to Authorization Table.
	valStr = getProperty("authorization.table.file", "config/authorization.table");
	if (valStr.startsWith(File.separator))
	    authorizationTableFile = new File(valStr);
	else 
	    authorizationTableFile = new File(ServerContext.getBaseFile(), valStr);
	if (!authorizationTableFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <authorization.table.file> "+valStr);	
	
	// Pointer to Scheduling Parameters.
	valStr = getProperty("scheduling.parameters.file", "config/scheduling.properties");
	if (valStr.startsWith(File.separator))
	    schedulingParametersFile = new File(valStr);
	else 
	    schedulingParametersFile = new File(ServerContext.getBaseFile(), valStr);
	if (!schedulingParametersFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <scheduling.parameters.file> "+valStr);	
	
	// Pointer to Weighting Parameters.
	valStr = getProperty("weighting.parameters.file", "config/weighting.properties");
	if (valStr.startsWith(File.separator))
	    weightingParametersFile = new File(valStr);
	else 
	    weightingParametersFile = new File(ServerContext.getBaseFile(), valStr);
	if (!weightingParametersFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <weighting.parameters.file> "+valStr);	
	
	// Pointer to Client Settings.
	valStr = getProperty("client.settings.file", "config/client.properties");
	if (valStr.startsWith(File.separator))
	    clientSettingsFile = new File(valStr);
	else 
	    clientSettingsFile = new File(ServerContext.getBaseFile(), valStr);
	if (!clientSettingsFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <client.settings.file> "+valStr);	

	// Pointer to News Table.
	valStr = getProperty("news.table.file", "config/news.properties");
	if (valStr.startsWith(File.separator))
	    newsTableFile = new File(valStr);
	else 
	    newsTableFile = new File(ServerContext.getBaseFile(), valStr);
	if (!newsTableFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <news.table.file> "+valStr);	
	
	// Pointer to Client Resources Directory.
	valStr = getProperty("client.resources.base.dir", "config/client");
	if (valStr.startsWith(File.separator))
	    clientResourcesBaseFile = new File(valStr);
	else 
	    clientResourcesBaseFile = new File(ServerContext.getBaseFile(), valStr);
	if (!clientResourcesBaseFile.isDirectory()) 
	    throw new IllegalArgumentException("Illegal value for <client.resources.base.dir> "+valStr);	
	    
	// Pointer to Instruments Registry.
	valStr = getProperty("instruments.registry.file", "config/instruments.properties");
	if (valStr.startsWith(File.separator))
	    instrumentsFile = new File(valStr);
	else 
	    instrumentsFile = new File(ServerContext.getBaseFile(), valStr);
	if (!instrumentsFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <instruments.registry.file> "+valStr);	
	    
	// Transaction config file.
	valStr = getProperty("transaction.manager.config.file", "config/dtms.properties");
	if (valStr.startsWith(File.separator))
	    dtmsConfigFile = new File(valStr);
	else 
	    dtmsConfigFile = new File(ServerContext.getBaseFile(), valStr);
	if (!dtmsConfigFile.exists()) 
	    throw new IllegalArgumentException("Illegal value for <transaction.manager.config.file> "+valStr);	
	
    }

   
    
}


